<?php 
/**
* Test Acl
*/
class DomArAclTestCase extends DomArTestUnitTestCase {

	public function setUp() {
    	parent::setUp();
    }
    
    public function tearDown() {
    	parent::tearDown();
    }

	public function testLazyLoad() {
		DomArTestClass_DomArAcl::getTable()->update();
		
		$a = new DomArTestClass_DomArAcl('a');
		$this->assertIdentical( $a->access('rights'), NULL);
		$this->assertEqual( get_class($a->rights), 'DomArAclRole' );
		
		$a->save();

		DomAr::flushStoredObjects();
		
		$a = DomArTestClass_DomArAcl::load( $a->id );
		$this->assertIdentical( $a->access('rights'), NULL);
		$this->assertEqual( get_class($a->rights), 'DomArAclRole' );
		
		$a->delete();
	}
	
	public function testAllowAndDeny() {
		$a = new DomArTestClass_DomArAcl('a');
		$a->rights->allow('edit');
		$a->rights->allow('read');
		$a->rights->deny('delete');
		
		$this->assertIdentical( $a->rights->resources['edit'], true );
		$this->assertIdentical( $a->rights->resources['read'], true );
		$this->assertIdentical( $a->rights->resources['delete'], false );
		
		$this->assertIdentical( $a->rights->changedResources['edit'], true );
		$this->assertIdentical( $a->rights->changedResources['read'], true );
		$this->assertIdentical( $a->rights->changedResources['delete'], true );
		
	}
	
	public function testRemove() {
		$a = new DomArTestClass_DomArAcl('a');
		$a->rights->allow('misc1');
		$a->rights->deny('misc2');
		
		$this->assertIdentical( $a->rights->resources['misc1'], true );
		$this->assertIdentical( $a->rights->resources['misc2'], false );
		$this->assertIdentical( $a->rights->changedResources['misc1'], true );
		$this->assertIdentical( $a->rights->changedResources['misc2'], true );
		
		$a->rights->remove('misc1');
		$a->rights->remove('misc2');
		
		$this->assertNotIdentical( $a->rights->resources['misc1'], true );
		$this->assertNotIdentical( $a->rights->resources['misc2'], false );
		$this->assertNotIdentical( $a->rights->changedResources['misc1'], true );
		$this->assertNotIdentical( $a->rights->changedResources['misc2'], true );
	
	}
	
	public function testIsAllowed() {
		$a = new DomArTestClass_DomArAcl('a');
		$a->rights->allow('edit');
		$a->rights->allow('read');
		$a->rights->deny('delete');
		
		$this->assertIdentical( $a->rights->isAllowed('edit'), true);
		$this->assertIdentical( $a->rights->isAllowed('read'), true);
		$this->assertIdentical( $a->rights->isAllowed('delete'), false);
		$this->assertIdentical( $a->rights->isAllowed('misc'), false);
	}

	public function testBasic() {
		DomArTestClass_DomArAcl::getTable()->update();
		
		$a = new DomArTestClass_DomArAcl('a');
		
		$a->rights->allow('edit');
		$a->rights->allow('read');
		$a->rights->deny('delete');
		
		$a->save();
		
		DomAr::flushStoredObjects();
		$a = DomArTestClass_DomArAcl::load( $a->getId() );
	
		$this->assertIdentical( $a->rights->isAllowed('edit'), true);
		$this->assertIdentical( $a->rights->isAllowed('read'), true);
		$this->assertIdentical( $a->rights->isAllowed('delete'), false);
		$this->assertIdentical( $a->rights->isAllowed('misc'), false);
		
		$a->rights->deny('edit');
		$a->rights->allow('delete');
		$a->rights->deny('run');
		$a->rights->allow('jump');
		
		$this->assertIdentical( $a->rights->isAllowed('edit'), false);
		$this->assertIdentical( $a->rights->isAllowed('delete'), true);
		$this->assertIdentical( $a->rights->isAllowed('run'), false);
		$this->assertIdentical( $a->rights->isAllowed('jump'), true);
		
		$a->save();

		DomAr::flushStoredObjects();
		$a = DomArTestClass_DomArAcl::load( $a->getId() );

		$this->assertIdentical( $a->rights->isAllowed('read'), true);
		$this->assertIdentical( $a->rights->isAllowed('edit'), false);
		$this->assertIdentical( $a->rights->isAllowed('delete'), true);
		$this->assertIdentical( $a->rights->isAllowed('run'), false);
		$this->assertIdentical( $a->rights->isAllowed('jump'), true);
		$this->assertIdentical( $a->rights->isAllowed('misc'), false);
		
		$a->rights->remove('run');
		$a->rights->remove('jump');
		
		$this->assertIdentical( $a->rights->isAllowed('run'), false);
		$this->assertIdentical( $a->rights->isAllowed('jump'), false);
		$this->assertIdentical( $a->rights->isUnknown('run'), true);
		$this->assertIdentical( $a->rights->isUnknown('jump'), true);
		
		DomAr::flushStoredObjects();
		$a = DomArTestClass_DomArAcl::load( $a->getId() );
		
		$this->assertIdentical( $a->rights->isAllowed('read'), true);
		$this->assertIdentical( $a->rights->isAllowed('edit'), false);
		$this->assertIdentical( $a->rights->isAllowed('delete'), true);
		$this->assertIdentical( $a->rights->isUnknown('run'), true);
		$this->assertIdentical( $a->rights->isUnknown('jump'), true);
		$this->assertIdentical( $a->rights->isAllowed('misc'), false);
		
		$a->delete();
		
		$this->assertTableEmpty( $a->getTableName() );
		$this->assertTableEmpty( $a->rights->getProperty()->getResourcesTableName() );
		
	}
	
	public function testSimpleRelations() {
		DomArTestClass_DomArAcl::getTable()->update();
		
		$other = new DomArTestClass_DomArAcl('other');
		$voter = new DomArTestClass_DomArAcl('voter');
		$visitor = new DomArTestClass_DomArAcl('visitor');
		
		
		$other->save();
		$voter->save();
		$visitor->save();	
		
		$other->rights->allow('view');
		$voter->rights->allow('vote');
		$visitor->rights->addParent($other);
		$visitor->rights->addParent($voter);

		$other->save();
		$voter->save();
		$visitor->save();	
		
		$this->assertIdentical( $other->rights->isAllowed('view'), true);
		$this->assertIdentical( $other->rights->isAllowed('vote'), false);
		
		$this->assertIdentical( $voter->rights->isAllowed('view'), false);
		$this->assertIdentical( $voter->rights->isAllowed('vote'), true);
		
		$this->assertIdentical( $visitor->rights->isAllowed('view'), true);
		$this->assertIdentical( $visitor->rights->isAllowed('vote'), true);
	
		DomAr::flushStoredObjects();
	
		$other = DomArTestClass_DomArAcl::load( $other->getId() );
		$this->assertIdentical( $other->rights->isAllowed('view'), true);
		$this->assertIdentical( $other->rights->isAllowed('vote'), false);
	
		$voter = DomArTestClass_DomArAcl::load( $voter->getId() );
		$this->assertIdentical( $voter->rights->isAllowed('view'), false);
		$this->assertIdentical( $voter->rights->isAllowed('vote'), true);
		
		$visitor = DomArTestClass_DomArAcl::load( $visitor->getId() );
		
		$this->assertIdentical( $visitor->rights->isAllowed('view'), true);
		$this->assertIdentical( $visitor->rights->isAllowed('vote'), true);

	}
	
	
	public function testRelations() {
		DomArTestClass_DomArAcl::getTable()->update();
		
		$other = new DomArTestClass_DomArAcl('other');
		$voter = new DomArTestClass_DomArAcl('voter');
		$visitor = new DomArTestClass_DomArAcl('visitor');
		$editor = new DomArTestClass_DomArAcl('editor');
		$admin = new DomArTestClass_DomArAcl('admin');
		$superAdmin = new DomArTestClass_DomArAcl('superAdmin');
		
		$visitor->save();
		$editor->save();
		$admin->save();
		$superAdmin->save();
		$other->save();
		$voter->save();
				
		$other->rights->allow('view');
		
		$voter->rights->allow('vote');
		
		$visitor->rights->addParent($other);
		$visitor->rights->addParent($voter);

		$editor->rights->allow('edit');
		$editor->rights->allow('add');
		$editor->rights->deny('vote');
		$editor->rights->addParent($visitor);
		
		$admin->rights->allow('delete');
		$admin->rights->addParent($editor);
			
		$superAdmin->rights->allow('vote');
		$superAdmin->rights->addParent($admin);
		

		$other->save();
		$voter->save();
		$visitor->save();
		$editor->save();
		$admin->save();
		$superAdmin->save();

		
		$this->assertIdentical( $other->rights->isAllowed('view'), true);
		$this->assertIdentical( $other->rights->isAllowed('vote'), false);
		$this->assertIdentical( $other->rights->isAllowed('add'), false);
		$this->assertIdentical( $other->rights->isAllowed('edit'), false);
		$this->assertIdentical( $other->rights->isAllowed('delete'), false);
		
		$this->assertIdentical( $voter->rights->isAllowed('view'), false);
		$this->assertIdentical( $voter->rights->isAllowed('vote'), true);
		$this->assertIdentical( $voter->rights->isAllowed('add'), false);
		$this->assertIdentical( $voter->rights->isAllowed('edit'), false);
		$this->assertIdentical( $voter->rights->isAllowed('delete'), false);
		
		$this->assertIdentical( $visitor->rights->isAllowed('view'), true);
		$this->assertIdentical( $visitor->rights->isAllowed('vote'), true);
		$this->assertIdentical( $visitor->rights->isAllowed('add'), false);
		$this->assertIdentical( $visitor->rights->isAllowed('edit'), false);
		$this->assertIdentical( $visitor->rights->isAllowed('delete'), false);
		
		$this->assertIdentical( $editor->rights->isAllowed('view'), true);
		$this->assertIdentical( $editor->rights->isAllowed('vote'), false);
		$this->assertIdentical( $editor->rights->isAllowed('add'), true);
		$this->assertIdentical( $editor->rights->isAllowed('edit'), true);
		$this->assertIdentical( $editor->rights->isAllowed('delete'), false);
		
		$this->assertIdentical( $admin->rights->isAllowed('view'), true);
		$this->assertIdentical( $admin->rights->isAllowed('vote'), false);
		$this->assertIdentical( $admin->rights->isAllowed('add'), true);
		$this->assertIdentical( $admin->rights->isAllowed('edit'), true);
		$this->assertIdentical( $admin->rights->isAllowed('delete'), true);
		
		
		
		$this->assertIdentical( $superAdmin->rights->isAllowed('view'), true);
		$this->assertIdentical( $superAdmin->rights->isAllowed('vote'), true);
		$this->assertIdentical( $superAdmin->rights->isAllowed('add'), true);
		$this->assertIdentical( $superAdmin->rights->isAllowed('edit'), true);
		$this->assertIdentical( $superAdmin->rights->isAllowed('delete'), true);
		

		
		$visitor->rights->removeParent( $voter );
		
		$this->assertIdentical( $other->rights->isAllowed('view'), true);
		$this->assertIdentical( $other->rights->isAllowed('vote'), false);
		$this->assertIdentical( $other->rights->isAllowed('add'), false);
		$this->assertIdentical( $other->rights->isAllowed('edit'), false);
		$this->assertIdentical( $other->rights->isAllowed('delete'), false);
		
		$this->assertIdentical( $voter->rights->isAllowed('view'), false);
		$this->assertIdentical( $voter->rights->isAllowed('vote'), true);
		$this->assertIdentical( $voter->rights->isAllowed('add'), false);
		$this->assertIdentical( $voter->rights->isAllowed('edit'), false);
		$this->assertIdentical( $voter->rights->isAllowed('delete'), false);
		
		$this->assertIdentical( $visitor->rights->isAllowed('view'), true);
		$this->assertIdentical( $visitor->rights->isAllowed('vote'), false); // this must be false, others are same as start.
		$this->assertIdentical( $visitor->rights->isAllowed('add'), false);
		$this->assertIdentical( $visitor->rights->isAllowed('edit'), false);
		$this->assertIdentical( $visitor->rights->isAllowed('delete'), false);
		
		$this->assertIdentical( $editor->rights->isAllowed('view'), true);
		$this->assertIdentical( $editor->rights->isAllowed('vote'), false);
		$this->assertIdentical( $editor->rights->isAllowed('add'), true);
		$this->assertIdentical( $editor->rights->isAllowed('edit'), true);
		$this->assertIdentical( $editor->rights->isAllowed('delete'), false);
		
		$this->assertIdentical( $admin->rights->isAllowed('view'), true);
		$this->assertIdentical( $admin->rights->isAllowed('vote'), false);
		$this->assertIdentical( $admin->rights->isAllowed('add'), true);
		$this->assertIdentical( $admin->rights->isAllowed('edit'), true);
		$this->assertIdentical( $admin->rights->isAllowed('delete'), true);
		
		$this->assertIdentical( $superAdmin->rights->isAllowed('view'), true);
		$this->assertIdentical( $superAdmin->rights->isAllowed('vote'), true);
		$this->assertIdentical( $superAdmin->rights->isAllowed('add'), true);
		$this->assertIdentical( $superAdmin->rights->isAllowed('edit'), true);
		$this->assertIdentical( $superAdmin->rights->isAllowed('delete'), true);
		
		DomAr::flushStoredObjects();


		$other = DomArTestClass_DomArAcl::load( $other->getId() );
		$this->assertIdentical( $other->rights->isAllowed('view'), true);
		$this->assertIdentical( $other->rights->isAllowed('vote'), false);
		$this->assertIdentical( $other->rights->isAllowed('add'), false);
		$this->assertIdentical( $other->rights->isAllowed('edit'), false);
		$this->assertIdentical( $other->rights->isAllowed('delete'), false);
		
		$voter = DomArTestClass_DomArAcl::load( $voter->getId() );
		$this->assertIdentical( $voter->rights->isAllowed('view'), false);
		$this->assertIdentical( $voter->rights->isAllowed('vote'), true);
		$this->assertIdentical( $voter->rights->isAllowed('add'), false);
		$this->assertIdentical( $voter->rights->isAllowed('edit'), false);
		$this->assertIdentical( $voter->rights->isAllowed('delete'), false);
		
		$visitor = DomArTestClass_DomArAcl::load( $visitor->getId() );
		$this->assertIdentical( $visitor->rights->isAllowed('view'), true);
		$this->assertIdentical( $visitor->rights->isAllowed('vote'), false);
		$this->assertIdentical( $visitor->rights->isAllowed('add'), false);
		$this->assertIdentical( $visitor->rights->isAllowed('edit'), false);
		$this->assertIdentical( $visitor->rights->isAllowed('delete'), false);
		
		$editor = DomArTestClass_DomArAcl::load( $editor->getId() );
		$this->assertIdentical( $editor->rights->isAllowed('view'), true);
		$this->assertIdentical( $editor->rights->isAllowed('vote'), false);
		$this->assertIdentical( $editor->rights->isAllowed('add'), true);
		$this->assertIdentical( $editor->rights->isAllowed('edit'), true);
		$this->assertIdentical( $editor->rights->isAllowed('delete'), false);
		
		$admin = DomArTestClass_DomArAcl::load( $admin->getId() );
		$this->assertIdentical( $admin->rights->isAllowed('view'), true);
		$this->assertIdentical( $admin->rights->isAllowed('vote'), false);
		$this->assertIdentical( $admin->rights->isAllowed('add'), true);
		$this->assertIdentical( $admin->rights->isAllowed('edit'), true);
		$this->assertIdentical( $admin->rights->isAllowed('delete'), true);
		
		$superAdmin = DomArTestClass_DomArAcl::load( $superAdmin->getId() );
		$this->assertIdentical( $superAdmin->rights->isAllowed('view'), true);
		$this->assertIdentical( $superAdmin->rights->isAllowed('vote'), true);
		$this->assertIdentical( $superAdmin->rights->isAllowed('add'), true);
		$this->assertIdentical( $superAdmin->rights->isAllowed('edit'), true);
		$this->assertIdentical( $superAdmin->rights->isAllowed('delete'), true);
		
		$other->delete();


		$this->assertIdentical( $voter->rights->isAllowed('view'), false);
		$this->assertIdentical( $voter->rights->isAllowed('vote'), true);
		$this->assertIdentical( $voter->rights->isAllowed('add'), false);
		$this->assertIdentical( $voter->rights->isAllowed('edit'), false);
		$this->assertIdentical( $voter->rights->isAllowed('delete'), false);
		

		$this->assertIdentical( $visitor->rights->isAllowed('view'), false);
		$this->assertIdentical( $visitor->rights->isAllowed('vote'), false);
		$this->assertIdentical( $visitor->rights->isAllowed('add'), false);
		$this->assertIdentical( $visitor->rights->isAllowed('edit'), false);
		$this->assertIdentical( $visitor->rights->isAllowed('delete'), false);
		
		$this->assertIdentical( $editor->rights->isAllowed('view'), false);
		$this->assertIdentical( $editor->rights->isAllowed('vote'), false);
		$this->assertIdentical( $editor->rights->isAllowed('add'), true);
		$this->assertIdentical( $editor->rights->isAllowed('edit'), true);
		$this->assertIdentical( $editor->rights->isAllowed('delete'), false);
		
		$this->assertIdentical( $admin->rights->isAllowed('view'), false);
		$this->assertIdentical( $admin->rights->isAllowed('vote'), false);
		$this->assertIdentical( $admin->rights->isAllowed('add'), true);
		$this->assertIdentical( $admin->rights->isAllowed('edit'), true);
		$this->assertIdentical( $admin->rights->isAllowed('delete'), true);
		
		$this->assertIdentical( $superAdmin->rights->isAllowed('view'), false);
		$this->assertIdentical( $superAdmin->rights->isAllowed('vote'), true);
		$this->assertIdentical( $superAdmin->rights->isAllowed('add'), true);
		$this->assertIdentical( $superAdmin->rights->isAllowed('edit'), true);
		$this->assertIdentical( $superAdmin->rights->isAllowed('delete'), true);
		
		
		
		$editor->delete();
		
		$this->assertIdentical( $admin->rights->isAllowed('view'), false);
		$this->assertIdentical( $admin->rights->isAllowed('vote'), false);
		$this->assertIdentical( $admin->rights->isAllowed('add'), false);
		$this->assertIdentical( $admin->rights->isAllowed('edit'), false);
		$this->assertIdentical( $admin->rights->isAllowed('delete'), true);
		
		$this->assertIdentical( $superAdmin->rights->isAllowed('view'), false);
		$this->assertIdentical( $superAdmin->rights->isAllowed('vote'), true);
		$this->assertIdentical( $superAdmin->rights->isAllowed('add'), false);
		$this->assertIdentical( $superAdmin->rights->isAllowed('edit'), false);
		$this->assertIdentical( $superAdmin->rights->isAllowed('delete'), true);
		
		$voter->delete();
		$visitor->delete();
		$admin->delete();
		$superAdmin->delete();
		
		$this->assertTableEmpty( $voter->getTableName() );
		$this->assertTableEmpty( $voter->getProperty('rights')->getResourcesTableName() );
		$this->assertTableEmpty( $voter->getProperty('rights')->getRelationsTableName() );

	}
	
	public function testLoop() {
		DomArTestClass_DomArAcl::getTable()->update();
		
		$a = new DomArTestClass_DomArAcl('a');
		$b = new DomArTestClass_DomArAcl('b');
		
		$a->save();
		$b->save();	
		
		$a->rights->addParent($b);
		$b->rights->addParent($a);
		$this->assertIdentical( $a->rights->isAllowed('misc'), false);

		$a->save();
		$b->save();
		$this->assertIdentical( $a->rights->isAllowed('misc'), false);
		DomAr::flushStoredObjects();
	
		$a = DomArTestClass_DomArAcl::load( $a->getId() );
		$this->assertIdentical( $a->rights->isAllowed('misc'), false);
		

	}
	
	public function testSerialize() {
		DomArTestClass_DomArAcl::getTable()->update();
		
		$a = new DomArTestClass_DomArAcl('a');
		$b = new DomArTestClass_DomArAcl('b');
		$c = new DomArTestClass_DomArAcl('c');
		
		$a->rights->allow('misc');
		$a->rights->deny('misc2');
		$a->rights->allow('misc3');
		$a->rights->deny('misc4');
		
		$a->save();
		$b->save();
		$c->save();
		
		
		$a->rights->addParent($b);
		
		$a->rights->deny('misc3');
		$a->rights->allow('misc4');
		$a->rights->addParent($c);
		DomAr::flushStoredObjects();
		
		$s =  DomArObject::unserialize($a->serialize());
		
		$this->assertEqual( $s->rights->resources, $a->rights->resources );
		$this->assertEqual( $s->rights->changedResources, $a->rights->changedResources );
		$this->assertEqual( $s->rights->resourcesLoaded, $a->rights->resourcesLoaded );
		
		$this->assertEqual( $s->rights->parentsLoaded, $a->rights->parentsLoaded );
		
		$par = $s->rights->parents;
		$this->assertTrue( isset($par[$b->id]) );
		$this->assertEqual( $par[$b->id]->getParent()->id, $b->id );
		
		$this->assertTrue( isset($par[$c->id]) );
		$this->assertEqual( $par[$c->id]->getParent()->id, $c->id );
		
		$par = $s->rights->newParents;
		$this->assertTrue( isset($par[$c->id]) );
		$this->assertEqual( $par[$c->id]->id, $c->id );
		
	}

}
?>